
#define ENV_C__

#include "Env.h"

#include <string.h>
#include "Bsp.h"
#include "BSP_RS485.h"
#include "WG.h"

//	#include "BlockDevice.h"
//	#include "BlockDeviceConfig.h"
#include "EnvStore.h"
#include "Debug.h"


#define ENV_VERSION		6

EnvData_T envData;
static uint8_t envLocked;
static uint8_t envUpdate;
uint8_t devSN[16];

void Env_Reset(void){
	envData.inited = 0xAA;
	envData.version = ENV_VERSION;
	memset(envData.rdCpuKey, 0xFF, sizeof(envData.rdCpuKey));
	envData.rdCpuEfId = 0x0001;
	envData.rdCpuDfId = 0x3F01;
	memset(envData.rdMfKey, 0xFF, sizeof(envData.rdMfKey));
	envData.rdMfBlock = 1;
	envData.rdMfOffset = 0;
	envData.wg = 34;
	envData.wgParityFlag = 1;
	envData.wgPulseWidth[0] = 40;
	envData.wgPulseWidth[1] = 10;
	envData.wgReverse = 1;
	envData.rdErrorWarnning = 1;
	envData.rdMode = 0x80;
	envData.rdSupport[0] = 0x0F;
	envData.rdSupport[1] = 0;
	envData.channelEnable = ENV_CH_485P | ENV_CH_485A;	//默认：关闭485主动上传。
	//卡号分割上传，0表示不分割
	envData.doorUnlockTime = 0;
	//Glz 2018.07.07 add for 读头统一配置
	envData.rdMifareFirst = 0; //CPU卡和Mifare卡内容，默认CPU卡优先
	envData.rdInfoOpenDoor = 0;
	envData.rdCpuKeyId = 0;
	envData.ContentStartPosition = 0;			//ao add
	envData.ContentLength = 8;					//ao add
	envData.Customer_Code[0] = 0;				//ao add
	envData.Customer_Code[1] = 0;				//ao add
	envData.Customer_Code[2] = 0;				//ao add
	envData.Customer_Code[3] = 0;				//ao add
	envData.Customer_CPU_Position = 9;			//ao add
	envData.Customer_M1_Position = 9;			//ao add
	envData.Snr4_StartPos = 0;
	envData.Snr4_Len = 4;
	envData.Snr8_StartPos = 4;
	envData.Snr8_Len = 4;
	envData.Options_select = 0; 				//disable Mifare/Cpu card key check function;  disable customer code selected.
	envData.backlight = 1;
	envData.devAddr = 1;
	envData.hidFormat = 0;						//不补0
	envData.baudrate = 115200;
	memcpy(envData.qrPwd, "100544", 6);
	envData.qrPwdLen = 6;
	envData.qrReverse = 1;
	envData.qrWorkMode = ENV_Qr_WorkMode_HNEncrypt;
	envData.qrValidity = 30;
	
	memset(envData.devSnr, 0x00, sizeof(envData.devSnr));	
}

#if 0
static void Env_Sync(void){
	EnvData_T e = envData;
	unsigned char i;

	BD_Lock();
	uint32_t address = BD_EnvAddress;
	BD_Erase(address);
	BD_Program(address, (uint8_t[]){0xAA}, 1);
	BD_Program(address + 1, &e, sizeof(e));
	BD_Unlock();
}
#endif 

//应用环境变量中的韦根配置
static void WG_ConfigApply(void){
	WG_Config(WG_Conf_Pairty, &envData.wgParityFlag, sizeof(envData.wgParityFlag));
	WG_Config(WG_Conf_Time, 
		(unsigned int []){envData.wgPulseWidth[0], envData.wgPulseWidth[1] * 10 + 100}, 
		sizeof(unsigned int) * 2);
}

void ReadModeApply(void) {
  switch (envData.rdMode) {
    case 0: {
      // CPU内容
      envData.rdSupport[0] = 0x01 << 0;
      envData.rdSupport[1] = 0x01 << 0;
    } break;
    case 1: {
      // MF内容
      envData.rdSupport[0] = 0x01 << 1;
      envData.rdSupport[1] = 0x01 << 1;
    } break;
    case 2: {
      // CPU和MF内容
      envData.rdSupport[0] = 0x01 << 1 | 0x01 << 0;
      envData.rdSupport[1] = 0x01 << 1 | 0x01 << 0;
    } break;
    case 3: {
      // CPU、MF和SFZ
      envData.rdSupport[0] = 0x01 << 2 | 0x01 << 1 | 0x01 << 0;
      envData.rdSupport[1] = 0;
    } break;
    case 4: {
      // MF
      envData.rdSupport[0] = 0x01 << 1;
      envData.rdSupport[1] = 0;
    } break;
    case 5: {
      // CPU和SFZ
      envData.rdSupport[0] = 0x01 << 2 | 0x01 << 0;
      envData.rdSupport[1] = 0;
    } break;
    default: { 
		
	} 
	break; 
	}
}


#if 0
static void Env_Load(void){
	unsigned char i;
	uint32_t address = BD_EnvAddress + 1;
//		BD_Lock();
	BD_Read(address, &envData, sizeof(envData));
//		BD_Unlock();
}
#endif 

void Env_SetWG26(void){
	envData.wg = 26;
	envData.Snr4_StartPos = 0;
	envData.Snr4_Len = 4;
	envData.Snr8_StartPos = 4;
	envData.Snr8_Len = 4;
	envData.wgParityFlag = 1;
	envData.wgPulseWidth[0] = 40;
	envData.wgPulseWidth[1] = 10;
	envData.wgReverse = 0;
	WG_ConfigApply();
}

#if 0
void Env_WG34(void){
	envData.wg = 34;
	envData.Snr4_StartPos = 0;
	envData.Snr4_Len = 4;
	envData.Snr8_StartPos = 4;
	envData.Snr8_Len = 4;
	envData.wgParityFlag = 1;
	envData.wgPulseWidth[0] = 40;
	envData.wgPulseWidth[1] = 10;
	envData.wgReverse = 0;
	WG_ConfigApply();
}
#endif 

/*在非任务环境下调用*/
void Env_Init(void){
	Bsp_GetUid((uint32_t*)devSN);
	EnvStore_Init();
	EnvStore_Read(&envData);
	envUpdate = 0;
	if(envData.inited != 0xAA || envData.version != ENV_VERSION){
	//若环境变量为初始化或环境变量存储版本与固件对应的版本不同，则环境变量恢复为默认值
		Env_Reset();
	//若不修改默认环境变量，则不存储环境变量
//			Env_Update();
	}
	WG_ConfigApply();
	ReadModeApply();
	if(envData.baudrate != 9600 && envData.baudrate != 115200){
		envData.baudrate = 9600;
	}
	BSP_RS485_SetBaud(envData.baudrate);
}


#if 0
void Env_Init(void){
	Bsp_GetUid((uint32_t*)devSN);
	Env_Load();
	envUpdate = 0;
	uint8_t flag;
	BD_Read(BD_EnvAddress, &flag, sizeof(flag));
	if(flag != 0xAA){
	//若环境变量为初始化或环境变量存储版本与固件对应的版本不同，则环境变量恢复为默认值
		Env_Reset();
	//若不修改默认环境变量，则不存储环境变量
//			Env_Update();
	}
	WG_ConfigApply();
	ReadModeApply();
}
#endif 


void Env_Update(void){
	envUpdate = 1;
}

void Env_Lock(void){
	envLocked = 1;
}

void Env_Unlock(void){
	envLocked = 0;
}

void Env_Service(void){
	if(envLocked){
		return;
	}
	if(envUpdate){
		envUpdate = 0;
		WG_ConfigApply();
		ReadModeApply();
		BSP_RS485_SetBaud(envData.baudrate);
//			Env_Sync();
		EnvStore_Write(&envData);
	}
}

